<template>
  <div class="universal-visualizer">
    <VueFlow
        :nodes="nodes"
        :edges="edges as any"
        :fit-view-on-init="true"
        :min-zoom="0.1"
        :max-zoom="4"
        @node-click="onNodeClick"
        @pane-click="onPaneClick"
        @nodes-initialized="onNodesInitialized"
        @vue-flow-init="onVueFlowInit"
        class="flow-instance"
        :default-edge-options="defaultEdgeOptions"
        :node-types="dynamicNodeTypes"
    >
      <!-- Restore Addons -->
      <Background v-if="appConfig.showBackground" :variant="BackgroundVariant.Dots" :gap="20" :size="1" />
      <MiniMap v-if="appConfig.showMiniMap" />
      <Controls
          v-if="appConfig.showControls"
          :show-zoom="appConfig.controlsShowZoom"
          :show-fit-view="appConfig.controlsShowFitView"
          :show-interactive="appConfig.controlsShowInteractive"
          :position="appConfig.controlsPosition"
      >
          <!-- USE the new component AND listen for event -->
          <UniversalVisualizerCustomControls @open-settings-dialog="handleOpenSettingsDialog" />
      </Controls>

      <!-- Node Details Drawer -->
      <el-drawer
          v-model="isDrawerVisible"
          :title="`Node Details: ${drawerNode?.data?.name || drawerNode?.id || 'N/A'}`"
          direction="rtl"
          size="40%"
          @closed="onDrawerClose"
      >
        <UniversalNodeDetails :node-id="drawerNode?.id" :node-data="drawerNode?.data" v-if="drawerNode" />
        <el-empty description="No node selected" v-else></el-empty>
      </el-drawer>

      <!-- RENDER the new settings dialog -->
       <UniversalVisualizerSettingsDialog v-model="showSettingsDialog" />

    </VueFlow>

  </div>
</template>

<script setup lang="ts">
import { computed, ref, watch, markRaw, type Component, nextTick } from 'vue';
// Core Vue Flow imports - Separate type imports
import { VueFlow, useVueFlow, Position } from '@vue-flow/core'
// Import UI Components from their respective packages
import { Background, BackgroundVariant } from '@vue-flow/background';
import { MiniMap } from '@vue-flow/minimap';
import { Controls } from '@vue-flow/controls';
import { NodeToolbar } from '@vue-flow/node-toolbar'
// Import types separately
import type { 
    Node, 
    Edge, 
    Connection, 
    NodeMouseEvent, 
    DefaultEdgeOptions, 
    Dimensions, 
    GraphNode, 
    GraphEdge,
} from '@vue-flow/core';
// Assume Viewport and VueFlowInstance might be internal or from a different entry point if not found
// If they are definitely needed, check Vue Flow's specific version/exports
// import type { Viewport, VueFlowInstance } from '@vue-flow/core';

// Import Element Plus components
import { ElDrawer, ElEmpty, ElButton, ElMessage, ElMessageBox, ElDialog, ElForm, ElFormItem, ElRadioGroup, ElRadio, ElTooltip, ElColorPicker, ElPopover, ElSwitch, ElIcon } from 'element-plus';
// Import Store and Node components
import { useUniversalEditorStore } from '@/stores/universalEditorStore';
import UniversalNode from './nodes/UniversalNode.vue';
import RenderFunctionNode from '@/components/renderFunctionComponents/RenderFunctionNode';
import UniversalNodeDetails from './UniversalNodeDetails.vue';
import appConfig from '@/config';
import { Delete, InfoFilled } from '@element-plus/icons-vue';
// Import composables
import { useBlobity } from '@/composables/useBlobity';
// Import the new store (remember to rename the file later)
import { useUniversalVisualizerSettingsStore } from '@/stores/universalVisualizerSettingsStore.ts'; // <-- Use the new store name
import type { ColoringMode, AttributeDisplayMode } from '@/stores/universalVisualizerSettingsStore.ts'; // <-- Import type from new store
// Import the default color for fallback
import { defaultElementObjectColor } from '@/config';
// IMPORT the new controls component
import UniversalVisualizerCustomControls from '@/components/settings/UniversalVisualizerCustomControls.vue';
// IMPORT the new settings dialog component
import UniversalVisualizerSettingsDialog from '@/components/settings/UniversalVisualizerSettingsDialog.vue';

// --- Initialize Blobity ---
useBlobity();

const store = useUniversalEditorStore();
const visualizerSettings = useUniversalVisualizerSettingsStore();

// --- Refs & Computed ---
const nodes = computed(() => store.flowElements.nodes);
const edges = computed(() => store.flowElements.edges);
const isDrawerVisible = ref(false);
const drawerNode = computed(() => store.drawerNodeData);
// ADD ref for the new settings dialog visibility
const showSettingsDialog = ref(false);

// --- ADD LOGGING FOR NODES DATA (Include hidden check) ---
watch(nodes, (newNodes) => {
  console.log('[UniversalVisualizer] Nodes data updated (watcher). Count:', newNodes?.length || 0);
  if (newNodes && newNodes.length > 0) {
      // Log details of the first node
      console.log('[UniversalVisualizer] First node data (watcher):', JSON.stringify(newNodes[0], null, 2));
      console.log('[UniversalVisualizer] First node position (watcher):', newNodes[0]?.position);
      console.log('[UniversalVisualizer] First node hidden status (watcher):', newNodes[0]?.hidden);
      // Check for any hidden nodes
      const hiddenCount = newNodes.filter(n => n.hidden).length;
      if (hiddenCount > 0) {
          console.warn(`[UniversalVisualizer] ${hiddenCount} node(s) have hidden=true in the updated nodes data (watcher). IDs:`, newNodes.filter(n => n.hidden).map(n => n.id));
      }
  } else {
      console.log('[UniversalVisualizer] Nodes data updated to empty (watcher).');
  }
}, { immediate: true, deep: true });

// --- Default Edge Options ---
const defaultEdgeOptions = ref<DefaultEdgeOptions>({
  type: 'smoothstep',
  style: { strokeWidth: 1.5, stroke: '#aaa' }, 
});

// --- Dynamic Node Types (Use markRaw) ---
const dynamicNodeTypes = computed(() => {
  const method = visualizerSettings.nodeRenderingMethod;
  // Determine the component based on the method
  const selectedComponent = method === 'template' 
                            ? UniversalNode 
                            : RenderFunctionNode;
  
  // Wrap the selected component with markRaw
  const nodeTypeMap = {
    universal: markRaw(selectedComponent),
  };
  
  // Keep the logs for now, they might still be useful
  console.log(`[UniversalVisualizer] dynamicNodeTypes computed. Method: ${method}`);
  console.log('[UniversalVisualizer] dynamicNodeTypes value:', nodeTypeMap);
  console.log('[UniversalVisualizer] Imported UniversalNode object:', UniversalNode);
  console.log('[UniversalVisualizer] Imported RenderFunctionNode object:', RenderFunctionNode);
  
  return nodeTypeMap;
});

// --- Watchers ---
watch(() => store.drawerNodeId, (newNodeId) => {
  isDrawerVisible.value = !!newNodeId;
});

// --- Event Handlers & Methods ---
const onNodeClick = (event: NodeMouseEvent) => {
  console.log('[UniversalVisualizer] Node clicked (selection toggle only):', event.node.id);
};
const onPaneClick = () => {
  console.log('[UniversalVisualizer] Pane clicked');
  store.selectNodeForDrawer(null);
};
const onDrawerClose = () => {
  console.log('[UniversalVisualizer] Drawer closed event');
  if (store.drawerNodeId !== null) {
    store.selectNodeForDrawer(null);
  }
};
const onNodesInitialized = () => {
  console.log('[UniversalVisualizer] Nodes Initialized');
  // REMOVE fitView call from here
  /*
  nextTick(() => {
    const fitViewOptions = { padding: 0.1 }; 
    vueFlowInstance.value?.fitView(fitViewOptions);
    console.log('[UniversalVisualizer] fitView called after nodes initialized');
  });
  */
};
const onVueFlowInit = (instance: any) => {
  console.log('[UniversalVisualizer] VueFlow Initialized');
  // Ensure fitView is called here with the provided instance
  instance.fitView({ padding: 0.1 }); 
};

// --- Node Toolbar Action ---
const handleShowDetails = (nodeId: string) => {
    console.log(`[UniversalVisualizer] Show details requested for node: ${nodeId}`);
    store.selectNodeForDrawer(nodeId);
};
const handleDeleteNode = async (nodeId: string) => {
    console.log(`[UniversalVisualizer] Delete requested for node: ${nodeId}`);
    try {
        await ElMessageBox.confirm(
            `确定要删除此节点及其所有子节点吗？此操作会尝试保存更改。`,
            '确认删除',
            {
                confirmButtonText: '删除',
                cancelButtonText: '取消',
                type: 'warning',
            }
        );
        await store.deleteNodeWithDescendants(nodeId);
        ElMessage.success('节点已删除。');
    } catch (error) {
        if (error === 'cancel' || error === 'close') {
             ElMessage.info('删除操作已取消。');
        } else {
             console.error('Error deleting node:', error);
             ElMessage.error(`删除节点时出错: ${store.error || '未知错误'}`);
        }
    }
};

// --- ADD Handler for the emitted event --- 
const handleOpenSettingsDialog = () => {
  showSettingsDialog.value = true;
};

console.log('[UniversalVisualizer] Component setup complete.');

</script>

<style lang="scss" scoped>
/* Ensure the component itself and the direct child container take full height/width */
.universal-visualizer {
  width: 100%;
  height: 100%;
  overflow: hidden; /* Prevent scrollbars on the container itself */
}

/* Style the VueFlow instance to fill its container */
.flow-instance {
  width: 100%;
  height: 100%;
}

/* Styles for the render function node if used */
.render-function-node {
  /* Basic styles similar to template node base */
  border-radius: 4px;
  padding: 10px;
  font-size: 12px;
  line-height: 1.4;

  .node-name {
    font-weight: bold;
    margin-bottom: 4px;
  }

  .node-content {
    font-style: italic;
    color: #555;
    margin-bottom: 6px;
  }

  .attribute-display-wrapper {
    /* Styles handled by computed style in the component */
    .attribute-summary {
      font-style: italic;
      color: #777;
    }
    .attribute-list {
      font-size: 0.9em;
      .attribute-item {
         display: flex; // Use flex for alignment
         gap: 4px; // Space between name and value
        .attr-name {
          font-weight: 500;
          color: #333;
        }
        .attr-value {
          color: #0679d1; // Example value color
        }
      }
      .more-attrs {
        font-style: italic;
        color: #999;
      }
    }
  }
}

/* Add specific dark mode styles for render function node if used */
.dark {
  .render-function-node {
    background-color: #2d3748; // Example dark background
    border-color: #4a5568; // Example dark border
    color: #e2e8f0; // Example dark text

    .node-content {
      color: #a0aec0;
    }
    .attribute-display-wrapper {
       border-top-color: #4a5568; // Darker separator
       .attribute-summary { color: #a0aec0; }
       .attribute-list {
         .attribute-item {
           .attr-name { color: #cbd5e0; }
           .attr-value { color: #63b3ed; } // Lighter blue for dark
         }
         .more-attrs { color: #718096; }
       }
    }
  }
}

</style>

<!-- Global style needed for popover class -->
<style lang="scss">
.attribute-popover,
.separator-popover,
.misc-settings-popover { /* Apply padding to all popovers */
  padding: 12px;
}
</style>
